/**
  ******************************************************************************
  * @file    uart.h
  * @author  hyseim software Team
  * @date    18-Aug-2023
  * @brief   This file provides all the tmp functions.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2020 Hyseim. Co., Ltd.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __UART_H__
#define __UART_H__

/* Includes ------------------------------------------------------------------*/
#include "assi.h"
#include "utils.h"

#ifdef __cplusplus
 extern "C" {
#endif

/** @addtogroup IM110GW_UART_Driver
  * @{
  */

/** @addtogroup UART
  * @{
  */


/* ================================================================================ */
/* ============== Universal Asyncronous Receiver / Transmitter (UART) ============= */
/* ================================================================================ */
typedef struct {
    union {
    __I  uint32_t RBR;             /*!< Receive Buffer Register,                             Address offset: 0x000 */
    __O  uint32_t THR;             /*!< Transmit Holding Register,                           Address offset: 0x000 */
    __IO uint32_t DLL;             /*!< Divisor Latch(Low),                                  Address offset: 0x000 */
    };
    union {
    __IO uint32_t DLH;             /*!< Divisor Latch(High),                                 Address offset: 0x004 */
    __IO uint32_t IER;             /*!< Interrupt Enable Register,                           Address offset: 0x004 */
    };
    union {
    __I  uint32_t IIR;             /*!< Interrupt Identification Register,                   Address offset: 0x008 */
    __O  uint32_t FCR;             /*!< FIFO Control Register,                               Address offset: 0x008 */
    };
    __IO uint32_t LCR;             /*!< Line Control Register,                               Address offset: 0x00C */
    __IO uint32_t MCR;             /*!< Modem Control Register,                              Address offset: 0x010 */
    __I  uint32_t LSR;             /*!< Line Status Register,                                Address offset: 0x014 */
    __I  uint32_t MSR;             /*!< Modem Status Register,                               Address offset: 0x018 */
    __IO uint32_t SCR;             /*!< Scratchpad Register,                                 Address offset: 0x01C */
         uint32_t RESERVED0[4];    /*!< Reserved,                                                    0x020 - 0x02C */
    union {
    __I  uint32_t SRBRn[16];       /*!< Shadow Receive Buffer Register,                              0x030 - 0x06C */
    __O  uint32_t STHRn[16];       /*!< Shadow Transmit Holding Register,                            0x030 - 0x06C */
    };
         uint32_t RESERVED1[3];    /*!< Reserved,                                                    0x070 - 0x078 */
    __I  uint32_t USR;             /*!< UART Status Register,                                Address offset: 0x07C */
    __I  uint32_t TFL;             /*!< Transmit FIFO Level,                                 Address offset: 0x080 */
    __I  uint32_t RFL;             /*!< Receive FIFO Level,                                  Address offset: 0x084 */
    __O  uint32_t SRR;             /*!< Software Reset Register,                             Address offset: 0x088 */
    __IO uint32_t SRTS;            /*!< Shadow Request to Send,                              Address offset: 0x08C */
    __IO uint32_t SBCR;            /*!< Shadow Break Control Register,                       Address offset: 0x090 */
         uint32_t RESERVED2;       /*!< Reserved,                                                            0x094 */
    __IO uint32_t SFE;             /*!< Shadow FIFO Enable,                                  Address offset: 0x098 */
    __IO uint32_t SRT;             /*!< Shadow RCVR Trigger,                                 Address offset: 0x09C */
    __IO uint32_t STET;            /*!< Shadow TX Empty Trigger,                             Address offset: 0x0A0 */
    __IO uint32_t HTX;             /*!< Halt TX,                                             Address offset: 0x0A4 */
    __O  uint32_t DMASA;           /*!< DMA Software Acknowledge,                            Address offset: 0x0A8 */
         uint32_t RESERVED3[5];    /*!< Reserved,                                                    0x0AC - 0x0BC */
    __IO uint32_t DLF;             /*!< Divisor Latch Fractional Value,                      Address offset: 0x0C0 */
    __IO uint32_t RAR;             /*!< Receive Address Register,                            Address offset: 0x0C4 */
    __IO uint32_t TAR;             /*!< Transmit Address Register,                           Address offset: 0x0C8 */
    __IO uint32_t EXTLCR;          /*!< Line Extended Control Register,                      Address offset: 0x0CC */
} UART_t;

#define UART0      ((UART_t*)&(((ASSI_t*)ASSI(0))->uart))
#define UART1      ((UART_t*)&(((ASSI_t*)ASSI(1))->uart))
#define UART2      ((UART_t*)&(((ASSI_t*)ASSI(2))->uart))
#define UART3      ((UART_t*)&(((ASSI_t*)ASSI(3))->uart))
#define UART4      ((UART_t*)&(((ASSI_t*)ASSI(4))->uart))
#define UART5      ((UART_t*)&(((ASSI_t*)ASSI(5))->uart))
#define UART6      ((UART_t*)&(((ASSI_t*)ASSI(6))->uart))
#define UART7      ((UART_t*)&(((ASSI_t*)ASSI(7))->uart))

/*------------------------------------------------------------------------------------------------------*/
/*---                       Universal Asyncronous Receiver / Transmitter (UART)                      ---*/
/*------------------------------------------------------------------------------------------------------*/
/********************************  Bit definition for UART_IER register  ********************************/
#define UART_IER_RDAIE              (0x1U << 0)          /*!< Received Data Available Interrupt Enable */
#define UART_IER_THREIE             (0x1U << 1)          /*!< Transmit Holding Register Empty Interrupt Enable */
#define UART_IER_RLSIE              (0x1U << 2)          /*!< Receiver Line Status Interrupt Enable */
#define UART_IER_MSIE               (0x1U << 3)          /*!< Modem Status Interrupt Enable */
#define UART_IER_PTIME              (0x1U << 7)          /*!< Programmable THRE Interrupt Mode Enable */

/********************************  Bit definition for UART_IIR register  ********************************/
#define UART_IIR_INTID_Msk          (0xFU)               /*!< Interrupt ID bit mask */
#define UART_IIR_INTID_MSI          (0x0U)               /*!< Modem status interrupt */
#define UART_IIR_INTID_NONE         (0x1U)               /*!< No interrupt pending */
#define UART_IIR_INTID_THRE         (0x2U)               /*!< Transmitter holding register empty */
#define UART_IIR_INTID_RDA          (0x4U)               /*!< Received data available interrupt */
#define UART_IIR_INTID_RLS          (0x6U)               /*!< Receiver line status interrupt */
#define UART_IIR_INTID_BUSY         (0x7U)               /*!< Busy detect */
#define UART_IIR_INTID_CTI          (0xCU)               /*!< character timeout indicator */

#define UART_IIR_FIFOSE_Pos         (6U)
#define UART_IIR_FIFOSE_Msk         (0x3U << UART_IIR_FIFOSE_Pos)

/********************************  Bit definition for UART_FCR register  ********************************/
#define UART_FCR_FIFOE              (0x1U << 0)          /*!< FIFO Enable */
#define UART_FCR_RFIFOR             (0x1U << 1)          /*!< RCVR FIFO Reset */
#define UART_FCR_XFIFOR             (0x1U << 2)          /*!< XMIT FIFO Reset */

/* This is used to select the empty threshold level at which the THRE Interrupts are generated when the mode is active. */
#define UART_FCR_TET_0              (0x0U << 4)          /*!< FIFO empty */
#define UART_FCR_TET_2              (0x1U << 4)          /*!< 2 characters in the FIFO */
#define UART_FCR_TET_4              (0x2U << 4)          /*!< FIFO 1/4 full */
#define UART_FCR_TET_8              (0x3U << 4)          /*!< FIFO 1/2 full */

/* This is used to select the trigger level in the receiver FIFO at which the Received Data Available Interrupt is generated. */
#define UART_FCR_RT_1               (0x0U << 6)          /*!< 1 character in the FIFO */
#define UART_FCR_RT_4               (0x1U << 6)          /*!< FIFO 1/4 full */
#define UART_FCR_RT_8               (0x2U << 6)          /*!< FIFO 1/2 full */
#define UART_FCR_RT_14              (0x3U << 6)          /*!< FIFO 2 less than full */


/********************************  Bit definition for UART_LCR register  ********************************/
#define UART_LCR_WLS_Msk            (0x3U << 0)          /*!< Word lenghth field mask bit */
#define UART_LCR_WLS_5BIT           (0x0U << 0)          /*!< Word lenghth is 5 bits */
#define UART_LCR_WLS_6BIT           (0x1U << 0)          /*!< Word lenghth is 6 bits */
#define UART_LCR_WLS_7BIT           (0x2U << 0)          /*!< Word lenghth is 7 bits */
#define UART_LCR_WLS_8BIT           (0x3U << 0)          /*!< Word lenghth is 8 bits */

#define UART_LCR_STOP_Msk            (0x1U << 2)          /*!< Stop bit select field mask bit */
#define UART_LCR_STOP_1BIT           (0x0U << 2)          /*!< 1 stop bit */
#define UART_LCR_STOP_2BIT           (0x1U << 2)          /*!< 2 stop bits (1.5 stop bits when data length is 5 bits) */

#define UART_LCR_PARITY_Msk         (0x7U << 3)          /*!< Parity field mask bit */
#define UART_LCR_PARITY_NONE        (0x0U << 3)          /*!< No parity */
#define UART_LCR_PARITY_ODD         (0x1U << 3)          /*!< Odd parity (Sets the parity bit so that the count of bits set is an odd number) */
#define UART_LCR_PARITY_EVEN        (0x3U << 3)          /*!< Even parity (Sets the parity bit so that the count of bits set is an even number) */
#define UART_LCR_PARITY_MARK        (0x5U << 3)          /*!< Mark parity (Leaves the parity bit set to 1) */
#define UART_LCR_PARITY_SPACE       (0x7U << 3)          /*!< Space parity (Leaves the parity bit set to 0) */


#define UART_LCR_BC                 (0x1U << 6)          /*!< Break Control Bit */
#define UART_LCR_DLAB               (0x1U << 7)          /*!< Divisor Latch Access Bit */


/********************************  Bit definition for UART_MCR register  ********************************/
#define UART_MCR_RTS                (0x1U << 1)          /*!< Request to Send */
#define UART_MCR_LB                 (0x1U << 4)          /*!< LoopBack Bit */
#define UART_MCR_AFCE               (0x1U << 5)          /*!< Auto Flow Control Enable */
#define UART_MCR_SIRE               (0x1U << 6)          /*!< SIR Mode Enable */

/********************************  Bit definition for UART_LSR register  ********************************/
#define UART_LSR_DR                 (0x1U << 0)          /*!< Data Ready bit */
#define UART_LSR_OE                 (0x1U << 1)          /*!< Overrun error bit */
#define UART_LSR_PE                 (0x1U << 2)          /*!< Parity error bit */
#define UART_LSR_FE                 (0x1U << 3)          /*!< Framing error bit */
#define UART_LSR_BI                 (0x1U << 4)          /*!< Break Interrupt bit */
#define UART_LSR_THRE               (0x1U << 5)          /*!< Transmit Holding Register Empty bit */
#define UART_LSR_TEMT               (0x1U << 6)          /*!< Transmitter Empty bit */
#define UART_LSR_RFE                (0x1U << 7)          /*!< Receiver FIFO Error bit */
#define UART_LSR_ADDR_RCVD          (0x1U << 8)          /*!< Address Received bit */

/********************************  Bit definition for UART_MSR register  ********************************/
#define UART_MSR_DCTS               (0x1U << 0)          /*!< Delta Clear to Send */
#define UART_MSR_CTS                (0x1U << 4)          /*!< Clear to Send */

/********************************  Bit definition for UART_USR register  ********************************/
#define UART_USR_BUSY               (0x1U << 0)          /*!< UART Busy */
#define UART_USR_TFNF               (0x1U << 1)          /*!< Transmit FIFO Not Full */
#define UART_USR_TFE                (0x1U << 2)          /*!< Transmit FIFO Empty */
#define UART_USR_RFNE               (0x1U << 3)          /*!< Receive FIFO Not Empty */
#define UART_USR_RFF                (0x1U << 4)          /*!< Receive FIFO Full */

/********************************  Bit definition for UART_TFL register  ********************************/
/********************************  Bit definition for UART_RFL register  ********************************/

/********************************  Bit definition for UART_SRR register  ********************************/
//This register is valid only when the DW_apb_uart is configured to have additional  shadow registers implemented (SHADOW = YES).
#define UART_SRR_UR                 (0x1U << 0)          /*!< UART Reset */
#define UART_SRR_RFR                (0x1U << 1)          /*!< RCVR FIFO Reset. This is a shadow register for the RCVR FIFO Reset bit (FCR[1]). */
#define UART_SRR_XFR                (0x1U << 2)          /*!< XMIT FIFO Reset. This is a shadow register for the XMIT FIFO Reset bit (FCR[2]). */

/********************************  Bit definition for UART_SRTS register  ********************************/
#define UART_SRTS_SRTS              (0x1U << 0)          /*!< Shadow Request to Send. This is a shadow register for the RTS bit (MCR[1]). */

/********************************  Bit definition for UART_SBCR register  *******************************/
#define UART_SBCR_SBCB              (0x1U << 0)          /*!< Shadow Break Control Bit. This is a shadow register for the Break bit (LCR[6]). */

/********************************  Bit definition for UART_SFE register  ********************************/
#define UART_SFE_SFE                (0x1U << 0)          /*!< Shadow FIFO Enable. This is a shadow register for the FIFO enable bit (FCR[0]). */

/********************************  Bit definition for UART_SRT register  ********************************/
/* Shadow RCVR Trigger. This is a shadow register for the RCVR trigger bits (FCR[7:6]). */
#define UART_SRT_LEV0               (0x0U)               /*!< 1 character in the FIFO */
#define UART_SRT_LEV1               (0x1U)               /*!< FIFO 1/4 full */
#define UART_SRT_LEV2               (0x2U)               /*!< FIFO 1/2 full */
#define UART_SRT_LEV3               (0x3U)               /*!< FIFO 2 less than full */

/********************************  Bit definition for UART_STET register  *******************************/
/* Shadow TX Empty Trigger. This is a shadow register for the TX empty trigger bits (FCR[5:4]). */
#define UART_STET_LEV0              (0x0U)               /*!< FIFO empty */
#define UART_STET_LEV1              (0x1U)               /*!< 2 characters in the FIFO */
#define UART_STET_LEV2              (0x2U)               /*!< FIFO 1/4 full */
#define UART_STET_LEV3              (0x3U)               /*!< FIFO 1/2 full */

/********************************  Bit definition for UART_HTX register  ********************************/
#define UART_HTX_HTX                (0x1U << 0)          /*!< Halt TX */

/********************************  Bit definition for UART_DMASA register  ******************************/
#define UART_DMASA                  (0x1U << 0)          /*!< DMA Software Acknowledge */

/********************************  Bit definition for UART_EXTLCR register  ********************************/
#define UART_EXTLCR_WLS_E           (0x1U << 0)          /*!< This bit is used to enable 9-bit data for transmit and receive transfers */
#define UART_EXTLCR_ADDR_MATCH      (0x1U << 1)          /*!< Address Match Mode */
#define UART_EXTLCR_SEND_ADDR       (0x1U << 2)          /*!< Send address control bit */
#define UART_EXTLCR_TRANSMIT_MODE   (0x1U << 3)          /*!< Transmit mode control bit */

/*--------------------------------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/

/**
  * @brief  UART Init Structure definition
  */

typedef struct
{
    uint32_t UART_BaudRate;                     /*!< This member configures the UART communication baud rate. */

    uint8_t  UART_WordLength;                   /*!< Specifies the number of data bits transmitted or received in a frame.
                                                    This parameter can be a value of @ref UART_Word_Length */

    uint8_t  UART_StopBits;                     /*!< Specifies the number of stop bits transmitted.
                                                    This parameter can be a value of @ref UART_Stop_Bits */

    uint8_t  UART_Parity;                       /*!< Specifies the parity mode.
                                                    This parameter can be a value of @ref UART_Parity */

    uint8_t  UART_AutoFlowControl;              /*!< Specifies the auto flow control mode.
                                                    This parameter can be a value of @ref UART_AutoFlowControl */

    FunctionalState_t UART_FIFO_Enable;         /*!< Specifies the FIFO Enable.
                                                    This parameter can be a value of @ref ENABLE or DISABLE */
} UART_Init_t;

/* Exported constants --------------------------------------------------------*/

/** @defgroup UART_Exported_Constants
  * @{
  */

/** @defgroup UART_Word_Length
  * @{
  */
#define UART_WordLength_5b          UART_LCR_WLS_5BIT
#define UART_WordLength_6b          UART_LCR_WLS_6BIT
#define UART_WordLength_7b          UART_LCR_WLS_7BIT
#define UART_WordLength_8b          UART_LCR_WLS_8BIT
/**
  * @}
  */


/** @defgroup UART_Stop_Bits
  * @{
  */
#define UART_StopBits_One           UART_LCR_STOP_1BIT
#define UART_StopBits_Two           UART_LCR_STOP_2BIT
#define UART_StopBits_OnePointFive  UART_LCR_STOP_2BIT
/**
  * @}
  */


/** @defgroup UART_Parity
  * @{
  */
#define UART_Parity_None            (UART_LCR_PARITY_NONE)
#define UART_Parity_Odd             (UART_LCR_PARITY_ODD)
#define UART_Parity_Even            (UART_LCR_PARITY_EVEN)
#define UART_Parity_Mark            (UART_LCR_PARITY_MARK)
#define UART_Parity_Space           (UART_LCR_PARITY_SPACE)
/**
  * @}
  */


/** @defgroup UART_AutoFlowControl
  * @{
  */
#define UART_AutoFlowControl_None       (0x00)
#define UART_AutoFlowControl_CTS        (UART_MCR_AFCE)
#define UART_AutoFlowControl_RTS_CTS    (UART_MCR_AFCE | UART_MCR_RTS)
/**
  * @}
  */


/** @defgroup UART_RxFIFOShadowThreshold
  * @{
  */
#define UART_RxFIFOThreshold_1    0x00
#define UART_RxFIFOThreshold_4    0x01
#define UART_RxFIFOThreshold_8    0x02
#define UART_RxFIFOThreshold_14   0x03
/**
  * @}
  */


/** @defgroup UART_TxFIFOShadowThreshold
  * @{
  */
#define UART_TxFIFOThreshold_0    0x00
#define UART_TxFIFOThreshold_2    0x01
#define UART_TxFIFOThreshold_4    0x02
#define UART_TxFIFOThreshold_8    0x03
/**
  * @}
  */


/** @defgroup UART_IT
  * @{
  */
#define UART_IT_RDA                 UART_IER_RDAIE
#define UART_IT_THRE                UART_IER_THREIE
#define UART_IT_RLS                 UART_IER_RLSIE
#define UART_IT_MSI                 UART_IER_MSIE
/**
  * @}
  */



/** @defgroup UART_INTID
  * @{
  */
#define UART_INTID_MSI              UART_IIR_INTID_MSI    /*!< Modem status interrupt */
#define UART_INTID_NONE             UART_IIR_INTID_NONE   /*!< No interrupt pending */
#define UART_INTID_THRE             UART_IIR_INTID_THRE   /*!< Transmitter holding register empty */
#define UART_INTID_RDA              UART_IIR_INTID_RDA    /*!< Received data available interrupt */
#define UART_INTID_RLS              UART_IIR_INTID_RLS    /*!< Receiver line status interrupt */
#define UART_INTID_BUSY             UART_IIR_INTID_BUSY   /*!< Busy detect */
#define UART_INTID_CTI              UART_IIR_INTID_CTI    /*!< character timeout indicator */
/**
  * @}
  */


/** @defgroup UART_Flags
  * @{
  */
#define UART_FLAG_BUSY              UART_USR_BUSY
#define UART_FLAG_TFNF              UART_USR_TFNF
#define UART_FLAG_TFE               UART_USR_TFE
#define UART_FLAG_RFNE              UART_USR_RFNE
#define UART_FLAG_RFF               UART_USR_RFF
/**
  * @}
  */


/** @defgroup UART_LINE_STATUS
  * @{
  */
#define UART_LINE_STATUS_DR         UART_LSR_DR
#define UART_LINE_STATUS_OE         UART_LSR_OE
#define UART_LINE_STATUS_PE         UART_LSR_PE
#define UART_LINE_STATUS_FE         UART_LSR_FE
#define UART_LINE_STATUS_BI         UART_LSR_BI
#define UART_LINE_STATUS_THRE       UART_LSR_THRE
#define UART_LINE_STATUS_TEMT       UART_LSR_TEMT
#define UART_LINE_STATUS_RFE        UART_LSR_RFE
#define UART_LINE_STATUS_ADDR_RCVD  UART_LSR_ADDR_RCVD
/**
  * @}
  */


/** @defgroup UART_MODEM_STATUS
  * @{
  */
#define UART_MODEM_STATUS_DCTS      UART_MSR_DCTS
#define UART_MODEM_STATUS_CTS       UART_MSR_CTS
/**
  * @}
  */

/**
  * @}
  */

/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

uint8_t UART_Init(UART_t* UARTx, uint32_t UART_Clk,UART_Init_t* UART_InitStruct);
void UART_StructInit(UART_Init_t* UART_InitStruct);
void UART_WriteData(UART_t* UARTx, uint16_t Data);
uint16_t UART_ReadData(UART_t* UARTx);
void UART_RxFIFOThresholdConfig(UART_t* UARTx, uint8_t Threshold);
void UART_TxFIFOThresholdConfig(UART_t* UARTx, uint8_t Threshold);
void UART_FIFOCmd(UART_t* UARTx, FunctionalState_t NewState);
void UART_ResetRxFIFO(UART_t* UARTx);
void UART_ResetTxFIFO(UART_t* UARTx);
void UART_ForceBreakCmd(UART_t* UARTx, FunctionalState_t NewState);
void UART_ProgrammableTHREModeCmd(UART_t* UARTx, FunctionalState_t NewState);
void UART_ITConfig(UART_t* UARTx, uint8_t UART_IT, FunctionalState_t NewState);
uint8_t UART_GetIntID(UART_t* UARTx);
FlagStatus_t UART_GetFlagStatus(UART_t* UARTx, uint32_t UART_FLAG);
uint32_t UART_GetLineStatus(UART_t* UARTx);
uint32_t UART_GetModemStatus(UART_t* UARTx);
void UART_ClearModemStatus(UART_t *UARTx);
void UART_ClearIntrBusyDetect(UART_t *UARTx);
void UART_ModemForceRtsPinState(UART_t* UARTx, SignalState_t NewState);
void UART_WaitSendFIFOEmpty(UART_t* UARTx);
void UART_WaitReceiveFIFORFL(UART_t* UARTx,int num);
void UART_Set9BitTransmitAddress(UART_t *UARTx, uint8_t addr);
void UART_Set9BitReceiveAddress(UART_t *UARTx, uint8_t addr);
void UART_9bitDataModeConfig(UART_t *UARTx);
void UART_LoopBackModeCmd(UART_t *UARTx, FunctionalState_t NewState);
void UART_IrDACmd(UART_t *UARTx, FunctionalState_t NewState);

/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

#endif /* __IM110GW_UART_H */
